//
//  RegistrationListViewController.m
//  HandheldHospital
//
//  Created by zhangchao on 16/2/27.
//  Copyright © 2016年 zhangchao. All rights reserved.
//

#import "RegistrationListViewController.h"
#import "DataManager.h"
#import "Registering.h"
#import "RegisteringCell.h"
#import <WXApi.h>
#import "CommonUtil.h"





NSString *AccessTokenKey = @"access_token";
NSString *PrePayIdKey = @"prepayid";
NSString *errcodeKey = @"errcode";
NSString *errmsgKey = @"errmsg";
NSString *expiresInKey = @"expires_in";

/**
 *  微信开放平台申请得到的 appid, 需要同时添加在 URL schema
 */
NSString * const WXAppId = @"wxd930ea5d5a258f4f";

/**
 * 微信开放平台和商户约定的支付密钥
 *
 * 注意：不能hardcode在客户端，建议genSign这个过程由服务器端完成
 */
NSString * const WXAppKey = @"L8LrMqqeGRxST5reouB0K66CaYAWpqhAVsq7ggKkxHCOastWksvuX1uvmvQclxaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K";

/**
 * 微信开放平台和商户约定的密钥
 *
 * 注意：不能hardcode在客户端，建议genSign这个过程由服务器端完成
 */
NSString * const WXAppSecret = @"db426a9829e4b49a0dcac7b4162da6b6";

/**
 * 微信开放平台和商户约定的支付密钥
 *
 * 注意：不能hardcode在客户端，建议genSign这个过程由服务器端完成
 */
NSString * const WXPartnerKey = @"8934e7d15453e97507ef794cf7b0519d";

/**
 *  微信公众平台商户模块生成的ID
 */
NSString * const WXPartnerId = @"1900000109";


#define kShared [DataManager defaultManager]

@interface RegistrationListViewController ()
@property (nonatomic, copy) NSString *timeStamp;
@property (nonatomic, copy) NSString *nonceStr;
@property (nonatomic, copy) NSString *traceId;
@end

@implementation RegistrationListViewController

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [kShared getRegisterArrayAndBlock:^{
        [self.tableView reloadData];
    }];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.title = @"挂号订单";
    self.tabBarController.tabBar.hidden = YES;
    [self.tableView registerClass:[RegisteringCell class] forCellReuseIdentifier:@"Cell"];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return kShared.registerArray.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    RegisteringCell *cell = [RegisteringCell cellWithTableView:tableView];
    Registering *registering = kShared.registerArray[indexPath.row];
    cell.nameLabel.text = registering.patient.name;
    cell.registeringType.text = registering.registerType;
    cell.hospitalname.text = registering.hospitalName;
    cell.registerDate.text = registering.registerDate;
    cell.keLei.text = registering.departments;
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    Registering *registering = kShared.registerArray[indexPath.row];
    if([registering.registerType isEqualToString:@"未交费"])
    {
        [self showAlertThreeButtonWithTitle:nil AndMessage:nil AndAlertStyle:UIAlertControllerStyleActionSheet AndOneButtonTitle:@"取消订单" AndTwoButtonTitle:@"支付订单" AndThreeButtonTitle:@"取消操作" AndOneBlock:^{
            [self cancelWithRegistering:registering];
        } AndTwoBlock:^{
            kShared.block = ^
            {//支付成功时调用
                [self showAlertOneButtonWithTitle:@"提示" AndMessage:nil AndAlertStyle:UIAlertControllerStyleAlert AndOneButtonTitle:@"支付成功" AndBlock:^{
                    [self isOKWithRegistering:registering];
                }];
            };
            //进行支付流程
            [self getAccessToken];
        } AndThreeBlock:nil];
    }
    else if([registering.registerType isEqualToString:@"已取消"])
    {
        [self showLabelWithString:@"此订单已取消" AndBlock:nil];
    }
    else if([registering.registerType isEqualToString:@"已支付"])
    {
        [self showLabelWithString:@"挂号已经完成" AndBlock:nil];
    }
    
    
}

//支付成功后改变数据库中订单的状态
- (void)isOKWithRegistering:(Registering *)registering
{
    AVQuery *query = [AVQuery queryWithClassName:@"Registering"];
    [query whereKey:@"currentUser" equalTo:registering.currentUser];
    [query whereKey:@"patient" equalTo:registering.patient];
    [query whereKey:@"hospitalName" equalTo:registering.hospitalName];
    [query whereKey:@"departments" equalTo:registering.departments];
    [query whereKey:@"registerDate" equalTo:registering.registerDate];
    [query whereKey:@"registerTime" equalTo:registering.registerTime];
    [query deleteAllInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if(succeeded)
        {
            Registering *reg = [Registering object];
            reg.currentUser = registering.currentUser;
            reg.patient = registering.patient;
            reg.hospitalName = registering.hospitalName;
            reg.departments = registering.departments;
            reg.cost = registering.cost;
            reg.registerDate = registering.registerDate;
            reg.registerTime = registering.registerTime;
            reg.registerType = @"已支付";
            [reg saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
                if(succeeded)
                {
                    [kShared getRegisterArrayAndBlock:^{
                        [self.tableView reloadData];
                    }];
                }
            }];
        }
    }];

}


//取消订单
- (void)cancelWithRegistering:(Registering *)registering
{
    AVQuery *query = [AVQuery queryWithClassName:@"Registering"];
    [query whereKey:@"currentUser" equalTo:registering.currentUser];
    [query whereKey:@"patient" equalTo:registering.patient];
    [query whereKey:@"hospitalName" equalTo:registering.hospitalName];
    [query whereKey:@"departments" equalTo:registering.departments];
    [query whereKey:@"registerDate" equalTo:registering.registerDate];
    [query whereKey:@"registerTime" equalTo:registering.registerTime];
    [query deleteAllInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
       if(succeeded)
       {
           Registering *reg = [Registering object];
           reg.currentUser = registering.currentUser;
           reg.patient = registering.patient;
           reg.hospitalName = registering.hospitalName;
           reg.departments = registering.departments;
           reg.cost = registering.cost;
           reg.registerDate = registering.registerDate;
           reg.registerTime = registering.registerTime;
           reg.registerType = @"已取消";
           [reg saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
              if(succeeded)
              {
                  [self showLabelWithString:@"订单取消成功" AndBlock:^{
                      [kShared getRegisterArrayAndBlock:^{
                          [self.tableView reloadData];
                      }];
                  }];
              }
           }];
       }
    }];
    
}



- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 170;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 10;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    //删除订单
    Registering *registering = kShared.registerArray[indexPath.row];
    //只有状态为已经取消的才能删除
    if([registering.registerType isEqualToString:@"已取消"])
    {
        [kShared.registerArray removeObjectAtIndex:indexPath.row];
        [registering deleteInBackground];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }
    else
    {
        [self showLabelWithString:@"此订单不可删除" AndBlock:nil];
    }
    
    
}


#pragma mark - 生成各种参数

- (NSString *)genTimeStamp
{
    return [NSString stringWithFormat:@"%.0f", [[NSDate date] timeIntervalSince1970]];
}

/**
 * 注意：商户系统内部的订单号,32个字符内、可包含字母,确保在商户系统唯一
 */
- (NSString *)genNonceStr
{
    return [CommonUtil md5:[NSString stringWithFormat:@"%d", arc4random() % 10000]];
}

/**
 * 建议 traceid 字段包含用户信息及订单信息，方便后续对订单状态的查询和跟踪
 */
- (NSString *)genTraceId
{
    return [NSString stringWithFormat:@"crestxu_%@", [self genTimeStamp]];
}

- (NSString *)genOutTradNo
{
    return [CommonUtil md5:[NSString stringWithFormat:@"%d", arc4random() % 10000]];
}

- (NSString *)genPackage
{
    // 构造参数列表
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    [params setObject:@"WX" forKey:@"bank_type"];
    [params setObject:@"挂号订单" forKey:@"body"];
    [params setObject:@"1" forKey:@"fee_type"];
    [params setObject:@"UTF-8" forKey:@"input_charset"];
    [params setObject:@"http://weixin.qq.com" forKey:@"notify_url"];
    [params setObject:[self genOutTradNo] forKey:@"out_trade_no"];
    [params setObject:WXPartnerId forKey:@"partner"];
    [params setObject:[CommonUtil getIPAddress:YES] forKey:@"spbill_create_ip"];
    [params setObject:@"1" forKey:@"total_fee"];    // 1 =＝ ¥0.01
    
    NSArray *keys = [params allKeys];
    NSArray *sortedKeys = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    
    // 生成 packageSign
    NSMutableString *package = [NSMutableString string];
    for (NSString *key in sortedKeys) {
        [package appendString:key];
        [package appendString:@"="];
        [package appendString:[params objectForKey:key]];
        [package appendString:@"&"];
    }
    
    [package appendString:@"key="];
    [package appendString:WXPartnerKey]; // 注意:不能hardcode在客户端,建议genPackage这个过程都由服务器端完成
    
    // 进行md5摘要前,params内容为原始内容,未经过url encode处理
    NSString *packageSign = [[CommonUtil md5:[package copy]] uppercaseString];
    package = nil;
    
    // 生成 packageParamsString
    NSString *value = nil;
    package = [NSMutableString string];
    for (NSString *key in sortedKeys) {
        [package appendString:key];
        [package appendString:@"="];
        value = [params objectForKey:key];
        
        // 对所有键值对中的 value 进行 urlencode 转码
        value = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)value, nil, (CFStringRef)@"!*'&=();:@+$,/?%#[]", kCFStringEncodingUTF8));
        
        [package appendString:value];
        [package appendString:@"&"];
    }
    NSString *packageParamsString = [package substringWithRange:NSMakeRange(0, package.length - 1)];
    
    NSString *result = [NSString stringWithFormat:@"%@&sign=%@", packageParamsString, packageSign];
    
    NSLog(@"--- Package: %@", result);
    
    return result;
}

- (NSString *)genSign:(NSDictionary *)signParams
{
    // 排序
    NSArray *keys = [signParams allKeys];
    NSArray *sortedKeys = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    
    // 生成
    NSMutableString *sign = [NSMutableString string];
    for (NSString *key in sortedKeys) {
        [sign appendString:key];
        [sign appendString:@"="];
        [sign appendString:[signParams objectForKey:key]];
        [sign appendString:@"&"];
    }
    NSString *signString = [[sign copy] substringWithRange:NSMakeRange(0, sign.length - 1)];
    
    NSString *result = [CommonUtil sha1:signString];
    NSLog(@"--- Gen sign: %@", result);
    return result;
}

- (NSMutableData *)getProductArgs
{
    self.timeStamp = [self genTimeStamp];
    self.nonceStr = [self genNonceStr]; // traceId 由开发者自定义，可用于订单的查询与跟踪，建议根据支付用户信息生成此id
    self.traceId = [self genTraceId];
    
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    [params setObject:WXAppId forKey:@"appid"];
    [params setObject:WXAppKey forKey:@"appkey"];
    [params setObject:self.timeStamp forKey:@"noncestr"];
    [params setObject:self.timeStamp forKey:@"timestamp"];
    [params setObject:self.traceId forKey:@"traceid"];
    [params setObject:[self genPackage] forKey:@"package"];
    [params setObject:[self genSign:params] forKey:@"app_signature"];
    [params setObject:@"sha1" forKey:@"sign_method"];
    
    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error: &error];
    NSLog(@"--- ProductArgs: %@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);
    return [NSMutableData dataWithData:jsonData];
}

#pragma mark - 主体流程

- (void)getAccessToken
{
    NSString *getAccessTokenUrl = [NSString stringWithFormat:@"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%@&secret=%@", WXAppId, WXAppSecret];
    
    NSLog(@"--- GetAccessTokenUrl: %@", getAccessTokenUrl);
    NSURLRequest *reuqest = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:getAccessTokenUrl]];
    
    //    self.request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:getAccessTokenUrl]];
    
    __weak RegistrationListViewController *weakSelf = self;
    //    __weak ASIHTTPRequest *weakRequest = self.request;
    [NSURLConnection sendAsynchronousRequest:reuqest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (!connectionError) {
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            
            NSString *accessToken = dict[AccessTokenKey];
            if (accessToken) {
                NSLog(@"--- AccessToken: %@", accessToken);
                
                __strong RegistrationListViewController *strongSelf = weakSelf;
                [strongSelf getPrepayId:accessToken];
            } else {
                NSString *strMsg = [NSString stringWithFormat:@"errcode: %@, errmsg:%@", dict[errcodeKey], dict[errmsgKey]];
                [weakSelf showAlertOneButtonWithTitle:@"提示" AndMessage:strMsg AndAlertStyle:UIAlertControllerStyleAlert AndOneButtonTitle:@"确定" AndBlock:nil];
            }
            
        }
        
        
    }];
    
}

- (void)getPrepayId:(NSString *)accessToken
{
    NSString *getPrepayIdUrl = [NSString stringWithFormat:@"https://api.weixin.qq.com/pay/genprepay?access_token=%@", accessToken];
    
    NSLog(@"--- GetPrepayIdUrl: %@", getPrepayIdUrl);
    
    NSMutableData *postData = [self getProductArgs];
    
    // 文档: 详细的订单数据放在 PostData 中,格式为 json
    NSMutableURLRequest *reuqest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:getPrepayIdUrl]];
    //    self.request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:getPrepayIdUrl]];
    [reuqest addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [reuqest addValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [reuqest setHTTPMethod:@"POST"];
    [reuqest setHTTPBody:postData];
    
    __weak RegistrationListViewController *weakSelf = self;
    //    __weak ASIHTTPRequest *weakRequest = self.request;
    [NSURLConnection sendAsynchronousRequest:reuqest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (!connectionError) {
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            
            NSString *prePayId = dict[PrePayIdKey];
            if (prePayId) {
                NSLog(@"--- PrePayId: %@", prePayId);
                
                // 调起微信支付
                PayReq *request   = [[PayReq alloc] init];
                request.partnerId = WXPartnerId;
                request.prepayId  = prePayId;
                request.package   = @"Sign=WXPay";      // 文档为 `Request.package = _package;` , 但如果填写上面生成的 `package` 将不能支付成功
                request.nonceStr  = weakSelf.nonceStr;
                request.timeStamp = [weakSelf.timeStamp longLongValue];
                
                // 构造参数列表
                NSMutableDictionary *params = [NSMutableDictionary dictionary];
                [params setObject:WXAppId forKey:@"appid"];
                [params setObject:WXAppKey forKey:@"appkey"];
                [params setObject:request.nonceStr forKey:@"noncestr"];
                [params setObject:request.package forKey:@"package"];
                [params setObject:request.partnerId forKey:@"partnerid"];
                [params setObject:request.prepayId forKey:@"prepayid"];
                [params setObject:weakSelf.timeStamp forKey:@"timestamp"];
                request.sign = [weakSelf genSign:params];
                
                // 在支付之前，如果应用没有注册到微信，应该先调用 [WXApi registerApp:appId] 将应用注册到微信
                //                [WXApi registerApp:WXAppId];
                [WXApi sendReq:request];
                NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",[dict objectForKey:@"appid"],request.partnerId,request.prepayId,request.nonceStr,(long)request.timeStamp,request.package,request.sign );
                
                //                NSLog(@"%ld", [WXApi sendReq:request]);
            } else {
                NSString *strMsg = [NSString stringWithFormat:@"errcode: %@, errmsg:%@", dict[errcodeKey], dict[errmsgKey]];
                [weakSelf showAlertOneButtonWithTitle:@"提示" AndMessage:strMsg AndAlertStyle:UIAlertControllerStyleAlert AndOneButtonTitle:@"确定" AndBlock:nil];
            }
        }
        
    }];
    
}


/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
